﻿Imports Microsoft.Msdn.Samples.BITS 'For the bits classes (joblist, job, etc)
Imports System.ServiceProcess 'For the service controller

Public Class FrmDownloads
 
    Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Dim Controller As New ServiceController("BITS")
        Dim Jobs As JobCollection
        Dim Job As Job
        Dim CurrentFile, FilesTotal As Integer
        Dim lstFile As ListViewItem

        Controller.Refresh() 'Rereads the states of the BITS service
        If Controller.Status <> ServiceControllerStatus.Running Then 'Is BITS not running?
            Exit Sub 'Exit this sub
        End If 'If Controller.Status <> ServiceControllerStatus.Running Then

        'If the service is not running or the controller and BITS wrapper have not been reset, an exception can occur.
        'This try statement will handle this case and leave the sub
        Try
            Jobs = ModBITS.BITS.GetListofJobs() 'Read all BITS jobs
        Catch ex As Exception 'Catch any exception
            'TODO: Enumerate various exceptions
            Exit Sub 'Leave sub
        End Try

        'Any selection in the job list will be lost, if the list is cleared. Therefore the list is just updated, while there
        'have been no changes to the jobs (add/remove).
        If Jobs.Count <> LViewDownloads.Items.Count Then 'Is the number of jobs and the no. of list entries different (Last run there have been more/less jobs)
            LViewDownloads.Items.Clear() 'Clear the job list
        End If 'If Jobs.Count <> LViewJobs.Items.Count Then



        FilesTotal = 0 'Reset the file counter
        For j = 0 To Jobs.Count - 1 'Enumerate the jobs
            FilesTotal = FilesTotal + Jobs(j).Files.Count 'Adds the file in the current job to the sum of files
        Next 'For j = 0 To Jobs.Count - 1

        'Any selection in the file list will be lost, if the list is cleared. Therefore the list is just updated, while there
        'have been no changes to the number of files.
        If FilesTotal <> LViewDownloads.Items.Count Then 'Has the number of files changed?
            LViewDownloads.Items.Clear() 'Clear the list of files
        End If 'If FilesTotal <> LViewDownloads.Items.Count Then

        'Reset the current file enumerator (-1, because the first items has to be zero!)
        CurrentFile = -1
        'This two loops are enumerating all jobs (j-loop) and within all files per job (i-loop)
        For j = 0 To Jobs.Count - 1 'Enumerating all jobs
            Job = Jobs.Item(j) 'Retrieve the job form the list of jobs


            For i = 0 To Job.Files.Count - 1 'Enumerating all files in the job
                CurrentFile += 1
                If LViewDownloads.Items.Count <> FilesTotal Then 'No. of jobs different to no. of list entries?
                    'In this block the no. of jobs have changed, therefore the list have been cleared and entry have to be added


                    'Add file to the listview
                    lstFile = New ListViewItem 'Create new instance of list entry
                    lstFile.Text = Job.Files(i).LocalName 'Add local file name to the list entry
                    If Job.Files(i).Progress.BytesTotal < 1000000000000000000 Then 'BITS sets a very high file size, if correct file size have not been ascertained. Is the value lower, Bandyt BITS assumes, that the file size is correct
                        'In this block the file size is assumed known
                        lstFile.SubItems.Add(Strings.Format(Job.Files(i).Progress.BytesTransferred, "##,##0") & " \ " & Strings.Format(Job.Files(i).Progress.BytesTotal, "##,##0"))
                    Else 'If Job.Files(i).Progress.BytesTotal < 1000000000000000000 Then
                        'In this block the file size is assumed unknown
                        lstFile.SubItems.Add("0 / ?") 'Add 0% as progress to the list entry
                    End If 'If Job.Files(i).Progress.BytesTotal < 1000000000000000000 Then
                    lstFile.Tag = j & "\" & i 'Add job no. and file no. as tag to the list entry
                    LViewDownloads.Items.Add(lstFile) 'Add new entry to the file list

                Else 'If LViewDownloads.Items.Count <> Jobs.Count Then
                    'In this block the no. of job have not been changed, therefore the list entries have to be updated only


                    LViewDownloads.Items(CurrentFile).Text = Job.Files(i).LocalName 'Update local file name
                    If Job.Files(i).Progress.BytesTotal < 1000000000000000000 Then 'Check if file size is below threshold, to ascertain if file size is known
                        'In this block, the file size is assumed known
                        LViewDownloads.Items(CurrentFile).SubItems(1).Text = Strings.Format(Job.Files(i).Progress.BytesTransferred, "##,##0") & " \ " & Strings.Format(Job.Files(i).Progress.BytesTotal, "##,##0") 'Update file size
                    Else
                        'In this block the file size is assumed unknown
                        LViewDownloads.Items(CurrentFile).SubItems(1).Text = ("0 / ?") 'Upadates ? as file size, indicating that file size is unknown
                    End If

                    LViewDownloads.Items(CurrentFile).Tag = j & "\" & i 'Update job no. and file no.
                End If
                'End of file enumeration
            Next

        Next 'For j = 0 To Jobs.Count - 1

    End Sub

    Private Sub FrmDownloads_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        e.Cancel = True
        Me.Hide()
    End Sub
End Class